#include"jpg.h"
void read_all_data(int fd, char *buf, int total_size)
{
	int n, m=0;
	while(total_size > 0)
	{
		n = read(fd, buf+m, total_size);
		if(n == -1)
		{
			perror("读取文件数据失败");
			exit(0);
		}

		if(n == 0)
			break;

		total_size -= n;
		m += n;
	}
}

char *load_file(char *jpgfile, struct image_info *minfo)
{
	// 获取文件的大小
	struct stat finfo;
	bzero(&finfo, sizeof(finfo));
	stat(jpgfile, &finfo);

	// 根据大小申请内存来存放 JPG 数据
	char *jpgdata = calloc(1, finfo.st_size);
	if(jpgdata == NULL)
	{
		perror("申请内存失败");
		exit(0);
	}

	// 将数据全部读到 jpgdata 中
	int fd = open(jpgfile, O_RDONLY);
	read_all_data(fd, jpgdata, finfo.st_size);


	/*********** 调用 JPG 库的固定套路 ***************/

	// 声明解压缩结构体，以及错误管理结构体
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;

	// 使用缺省的出错处理来初始化解压缩结构体
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);

	// 配置该cinfo，使其从jpgdata中读取jpg_size个字节
	// 这些数据必须是完整的JPEG数据
	jpeg_mem_src(&cinfo, jpgdata, finfo.st_size);


	// 读取JPEG文件的头，并判断其格式是否合法
	int ret = jpeg_read_header(&cinfo, true);
	if(ret != 1)
	{
		fprintf(stderr, "[%d]: jpeg_read_header failed: "
			"%s\n", __LINE__, strerror(errno));
		exit(0);
	}

	// 开始解压
	jpeg_start_decompress(&cinfo);

	minfo->width = cinfo.output_width;
	minfo->height = cinfo.output_height;
	minfo->pixel_size = cinfo.output_components;

	int row_stride = minfo->width * minfo->pixel_size;

	// 根据图片的尺寸大小，分配一块相应的内存rgbdata
	// 用来存放从jpgdata解压出来的图像数据
	unsigned long rgb_size;
	unsigned char *rgbdata;
	rgb_size = minfo->width *
			minfo->height * minfo->pixel_size;
	rgbdata = (unsigned char *)calloc(1, rgb_size);

	// 循环地将图片的每一行读出并解压到rgbdata中
	int line = 0;
	while(cinfo.output_scanline < cinfo.output_height)
	{
		unsigned char *buffer_array[1];
		buffer_array[0] = rgbdata +
				(cinfo.output_scanline) * row_stride;
		jpeg_read_scanlines(&cinfo, buffer_array, 1);
	}

	// 解压完了，将jpeg相关的资源释放掉
 	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	free(jpgdata);

	

	return rgbdata;
}

void display(char *jpgfile,char *fbmem,struct fb_var_screeninfo *vinfo,int xoffset, int yoffset)
{
		
	struct image_info minfo;
	bzero(&minfo,sizeof(minfo));
	char *rgbdata = load_file(jpgfile, &minfo);
				
	int lcd_w = vinfo->xres - xoffset;
	int lcd_h = vinfo->yres - yoffset;


	int rgb_offset = 0;
	int lcd_offset = 0;

	int i,j;
	//将像素点逐行写入LCD屏幕	

	fbmem += (yoffset * vinfo->xres + xoffset) * vinfo->bits_per_pixel/8;
	for(j=0; j<lcd_h && j<minfo.height; j++)
	{
		for(i=0; i<lcd_w && i<minfo.width; i++)
		{
			rgb_offset = minfo.pixel_size*i + minfo.width*minfo.pixel_size*j;
			lcd_offset = (vinfo->bits_per_pixel/8)*i + (vinfo->xres*vinfo->bits_per_pixel/ 8)*j;

			memcpy(fbmem+vinfo->red.offset/8+lcd_offset,  rgbdata+rgb_offset+0,  1);
			memcpy(fbmem+vinfo->green.offset/8+lcd_offset,rgbdata+rgb_offset+1,1);
			memcpy(fbmem+vinfo->blue.offset/8+lcd_offset, rgbdata+rgb_offset+2, 1);
		}
	}
	
	free(rgbdata);

}
void showMain(char *fbmem,struct fb_var_screeninfo *vinfo,int xoffset, int yoffset)
{
	display(background,fbmem,vinfo,0,0);
	int i;
	for(i=0;i<KEY;i++)
	{
		display(key_on,fbmem,vinfo,xoffset+W_key*i,yoffset);
	}
}
char *readFrist(int lcd)
{
	char *buf=calloc(1,800*480*4);
	read(lcd, buf,800*480*4);
	return buf;

}
void showFrist(char *rgbdata,char *fbmem,struct fb_var_screeninfo *vinfo,int xoffset, int yoffset)
{
		
	int lcd_w = vinfo->xres - xoffset;
	int lcd_h = vinfo->yres - yoffset;


	int rgb_offset = 0;
	int lcd_offset = 0;

	int i,j;
	//将像素点逐行写入LCD屏幕	
	//bzero(fbmem,sizeof(fbmem));
	for(i=0;i<vinfo->xres*vinfo->yres;i++)
	{
		memcpy(fbmem+i*4,rgbdata+i*4,4);	
	}
}
